package com.ericsson.enap.modules.autoCheck.service.impl;

import cn.hutool.core.date.DateUtil;
import com.ericsson.enap.modules.autoCheck.entity.AutoCheck;
import com.ericsson.enap.modules.autoCheck.entity.AutoCheckItem;
import com.ericsson.enap.modules.autoCheck.entity.VisExcelModuleDetail;
import com.ericsson.enap.modules.autoCheck.mapper.VisExcelModuleDetailMapper;
import com.ericsson.enap.modules.autoCheck.service.EopsTemplateScheduleService;
import com.ericsson.enap.modules.autoCheck.service.IEopsTemplateExecuteService;
import com.ericsson.enap.modules.autoCheck.task.AutoCheckScheduleTask;
import com.ericsson.enap.modules.base.entity.EnipBaseNetelement;
import com.ericsson.enap.modules.base.mapper.EnipBaseNetelementMapper;
import com.ericsson.epc.modules.autocheck.entity.EpcVisExcelModuleDetail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @description: 2222
 * @author: chenhongbo
 * @create: 2022-03-18 15:51
 */

@Service
public class EopsTemplateExecuteServiceImpl implements IEopsTemplateExecuteService {

    @Value("${TpXmlPathTxt}")
    private String rootPath;

    @Autowired
    VisExcelModuleDetailMapper visExcelModuleDetailMapper;

    @Autowired
    EnipBaseNetelementMapper enipBaseNetelementMapper;


    @Override
    public AutoCheck execEopsTemplate(Long netId, Long excelId) {

        EnipBaseNetelement netElement = enipBaseNetelementMapper.selectEnipBaseNetelementById(netId);
        if(netElement == null) {
            return null;
        }
        List<VisExcelModuleDetail> visExcelModuleDetailList = visExcelModuleDetailMapper.getModuleDetailsByExcelIds(String.valueOf(excelId));
        if(visExcelModuleDetailList.size() > 0) {
            AutoCheckScheduleTask.writeToJsonFile(visExcelModuleDetailList, rootPath);
            String command = "/usr/bin/perl -w /opt/Ericsson/core/bin/eops.pl";
            command += " -ip " + netElement.getIp4() + " -user " + netElement.getUsername() + " -password '" + netElement.getPassword()
                    + "' -conf_file " + rootPath + excelId + "_"
                    + visExcelModuleDetailList.get(0).getModuleId() + ".txt -rootpassword '" + netElement.getRootPassword() + "'";
            return execAutoTemplateCheckCmd(command, Math.toIntExact(netId), Math.toIntExact(excelId), visExcelModuleDetailList.get(0).getModuleId(), DateUtil.now(), visExcelModuleDetailList);
        }
        return null;
    }


    @Override
    public AutoCheck execAutoTemplateCheckCmd(String command, Integer netId, int excelId, int moduleId,String fetchDate,  List<VisExcelModuleDetail> moduleDetailList) {
        Process proc = null;
        String[] cmd = new String[3];
        cmd[0] = "sh";
        cmd[1] = "-c";
        cmd[2] = command;
        BufferedReader br = null;
        String line = null;
        AutoCheck autoCheck = new AutoCheck();
        autoCheck.setCheckTime(fetchDate);
        autoCheck.setNetId(netId);
        autoCheck.setVisexcelId(excelId);
        try {
            proc = Runtime.getRuntime().exec(cmd);// 测试时需要注释掉
            br = new BufferedReader(new InputStreamReader(proc.getInputStream(), Charset.forName("UTF-8")), 10 * 1024 * 1024);// 测试时需要注释掉

			/*if(excelId == 77) {
				br = readFile("F:/amf.txt");//测试代码
			} else if(excelId == 89) {
				br = readFile("F:/smf.txt");//测试代码
			}*/
            Thread.sleep(200);
            boolean isValidLog = false;
            boolean isEnd = false;
            StringBuilder sb = new StringBuilder();
            while ((line = br.readLine()) != null) {
                if(line.contains("SYSTEM-PRINT") || isEnd) {

                    if(sb.length() > 0) {
                        AutoCheckItem item1 = autoCheck.getAutoCheckItemList().get(autoCheck.getAutoCheckItemList().size()-1);
                        item1.setCheckLog(sb.toString());

                        //判断日志状态 全不成功 :0, 全部成功 :1 , 部分成功: 2
                        int totalCount = getTotalItem(sb.toString(),"<font color"); //总条数
                        int errorCount = getTotalItem(sb.toString(),"#f00000"); //失败数
                        int successCount = getTotalItem(sb.toString(),"#00b000"); //成功数

                        if(totalCount == successCount) {
                            //全部成功
                            item1.setItemResult(1);
                        } else if(totalCount == errorCount) {
                            //全部失败
                            item1.setItemResult(0);
                        } else {
                            //部分成功
                            item1.setItemResult(2);
                        }
                        sb.setLength(0);
                        isValidLog = false;
                        if(isEnd) break;
                    }

                    List<VisExcelModuleDetail> subDetail = findList(excelId,moduleId,line,moduleDetailList);
                    if(subDetail != null && subDetail.size()>0) {
                        isValidLog = true;
                        AutoCheckItem item = new AutoCheckItem();
                        VisExcelModuleDetail d = subDetail.get(0);
                        item.setNetId(netId);
                        item.setVisexcelId(excelId);
                        item.setDetailItemId(d.getId());
                        item.setItemName(d.getConfCmd().substring(13));
                        autoCheck.getAutoCheckItemList().add(item);
                    }

                } else {
                    if(isValidLog) {
                        if(line.contains("EOPS RUN SUCCESS")) {
                            isEnd = true;
                            continue;
                        } else if(line.contains("EOPS RUN STATUS")) {
                            continue;
                        }
                        sb.append(line).append("</br>");
                    }
                }

            }
            calcCheckResult(autoCheck);
            br.close();
            proc.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (proc != null) {
                proc.destroy();
            }

        }

        return autoCheck;
    }


    private List<VisExcelModuleDetail> findList(int excelId, int moduleId, String confCmd,List<VisExcelModuleDetail> moduleDetailList) {
        List<VisExcelModuleDetail> moduleList = new ArrayList<>();
        //List<VisExcelModuleDetail> moduleList = moduleDetailList.stream().filter(e -> e.getExcelId().intValue() == excelId && e.getModuleId().intValue() == moduleId && e.getConfCmd().contains("SYSTEM-PRINT") && confCmd.contains(e.getConfCmd().substring(13))).collect(Collectors.toList());
        for(VisExcelModuleDetail detail : moduleDetailList) {
            if(detail.getExcelId().intValue() == excelId && detail.getModuleId().intValue() == moduleId && detail.getConfCmd().contains("SYSTEM-PRINT")) {
                if(confCmd.contains(detail.getConfCmd().substring(13))) {
                    moduleList.add(detail);
                }

            }
        }

        return moduleList;
    }

    private int getTotalItem(String srcText,String findText) {
        int count = 0;
        Pattern p = Pattern.compile(findText);
        Matcher m = p.matcher(srcText);
        while(m.find()) {
            count++;
        }
        return count;
    }

    private void calcCheckResult(AutoCheck autoCheck) {
        List<AutoCheckItem> items = autoCheck.getAutoCheckItemList();
        int totalCount = 0;
        int allErrorCount = 0;
        int allSuccessCount = 0;
        for (AutoCheckItem item : items) {
            totalCount ++;
            if(item.getItemResult().intValue() == 0) {
                //全不成功
                allErrorCount ++;
            } else if(item.getItemResult().intValue() == 1) {
                //全部成功
                allSuccessCount ++;
            } else if(item.getItemResult().intValue() == 2) {
                //部分成功
                autoCheck.setCheckResult(2);
                return;
            }
        }
        if(totalCount == allErrorCount) {
            autoCheck.setCheckResult(0);
        } else if(totalCount == allSuccessCount) {
            autoCheck.setCheckResult(1);
        } else {
            autoCheck.setCheckResult(2);
        }

    }
}
